#include <iostream>

template <typename T, T... Values>
struct CompileTimeArray {
    using ValueType = T;
    static constexpr size_t Size = sizeof...(Values);
    static constexpr T Data[] = {Values...};
};

template <typename T, T... Values>
constexpr T CompileTimeArray<T, Values...>::Data[];

template <size_t Index, typename T, T... Values>
constexpr T Get(CompileTimeArray<T, Values...>) {
    static_assert(Index < sizeof...(Values), "Index out of range");
    return CompileTimeArray<T, Values...>::Data[Index];
};

int main() {
    using MyArray = CompileTimeArray<int, 1, 2, 3, 4, 5>;

    constexpr int size = MyArray::Size;
    constexpr int first = Get<0>(MyArray{});
    constexpr int third = Get<2>(MyArray{});
    constexpr int last = Get<size - 1>(MyArray{});

    std::cout << "MyArray::Size: " << size << std::endl;             // 输出 5
    std::cout << "Get<0>(MyArray{}): " << first << std::endl;        // 输出 1
    std::cout << "Get<2>(MyArray{}): " << third << std::endl;        // 输出 3
    std::cout << "Get<size - 1>(MyArray{}): " << last << std::endl;  // 输出 5

    return 0;
}
